feat(types)!: retire ComponentInput.label / defaultValue / advanced as ADR-0049 tombstones (objectui#7493 item 1 / objectui#7781) - #7932
Conversation
…s ADR-0049 tombstones (objectui#7493 item 1, objectui#7781) The three ComponentInput keys the manifest serializer does not forward, and that nothing reads on any publication or consumption path, are retired on both faces under the maintainer's ruling A of 2026-09-06. Route measured on the built face before editing: ComponentInputSchema is a non-strict z.object, so an undeclared key parses green and is silently stripped -- a deletion would have swallowed 1,162 authored values in silence. So each key stays declared and refuses BY NAME: `?: never` on the interface and retirementTombstone() on the Zod mirror (the objectui#5905 shape). - base.ts / base.zod.ts: three tombstones with the RETIRED docblocks (the census, the serializer's six forwarded keys, the authorship counts, what to write instead: nothing) - every in-repo authoring site deleted: 1,197 keys across 109 registration files (the 908 / 245 / 9 the inputs-literal census counted, plus the three standalone ComponentInput[] arrays), html-elements' PER_TAG_INPUTS record, ELEMENT_DATA_SOURCE_INPUT's label, and the WidgetRegistry seam copy (the one non-test write, which fed nothing) - the nine defaultValue-reading tests re-pinned against the renderer's ACTUAL default (its own fallback read or defaultProps); two shadow-default assertions dropped with the reason on the line; the icon coupling pin keeps its one remaining declared spelling - new pin component-input-retired-keys-7493: both faces refuse at path with the guidance, tsc legs at a real registration shape, forwarded-key controls (accepted and value-enforced), serializer forward set read off disk, an eight-tombstone census of the interface on both faces, and a tree-scoped absence census over every inputs array under packages/ and apps/ - widget.ts records the third divergence (WidgetInput keeps its three, measured reader-less now: objectui#7911); four docs guides stop authoring the keys; changeset (types minor, "Breaking for authored metadata", patch entries for the registration cleanups) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BAZFhALsQsGqxui8sNqM8s
…` too `tsc` found the one registration array the inputs-literal census could not see: `treeInputs` is a bare const referenced from two registrations. Its two `label` writes go the way of the other 1,197; the changeset totals and its patch list follow. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BAZFhALsQsGqxui8sNqM8s
…nc once The re-pin added a second `readFileSync` import beside the one the file already carried; `tsc -p tsconfig.test.json` refused the duplicate. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BAZFhALsQsGqxui8sNqM8s
…ponent-input-retire-dead-keys
…lts it used to read off `defaultValue` `sampleFor` seeded `relationshipValueField`, `showHeader`, `location`, `align`, `variant` and `size` from the registrations' declared defaults, which happened to be the renderers' own fallbacks and the one configuration under which the probe is askable. With `ComponentInput.defaultValue` retired the generic type samples took over — `'x'` for a parent field, the header chrome on, a location with no actions — and three blocks stopped reaching. The six values now sit in SAMPLE_BY_INPUT beside the read each mirrors. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BAZFhALsQsGqxui8sNqM8s
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
Contract review (clause ②) — PASS on content; landing on green — PR #7932 at head
|
| # | claim | reading | verdict |
|---|---|---|---|
| 1 | Route measured before chosen: ComponentInputSchema is a non-strict z.object, an undeclared key is silently stripped on the built face (control: the objectui#5905 tombstone min refuses) ⇒ deletion would trade one silent no-op for another; tombstone on both faces, the objectui#5905 / PR #7639 shape |
Diff read: three retirementTombstone() members with one guidance string each; ?: never with the RETIRED docblocks carrying census, ruling and remedy. |
correct |
| 2 | Reader census: every non-test consumer of ComponentMeta.inputs enumerated; the serializer forwards exactly six keys; the only non-test touch of the three was WidgetRegistry's write, now deleted |
WidgetRegistry.ts hunk drops the three copies and says why; WidgetInput keeps its own members (widget-manifest face, unruled) — recorded in widget.ts as divergence 3 and filed as #7911. |
correct |
| 3 | Authorship census with controls (name 951 / type 951): label 908, defaultValue 245, advanced 9; 1,199 keys deleted across 110 files plus the standalone arrays and the two named arrays tsc found; post-deletion census 0/0/0 with controls unchanged, carried as a tree-scoped pin |
Sampled registration confirms the shape (only label: / defaultValue: lines removed; one comment rewritten). The two RED intermediate consumer builds were real finds, fixed. |
correct |
| 4 | Nine defaultValue-reading test files re-pinned against the renderer's actual default (own fallback read or defaultProps), two shadow-restating assertions dropped with the reason on the line |
Table read; the right direction — a pin on a declaration nothing reads was never coverage. | correct |
| 5 | New 23-test pin: both faces refuse at path with guidance, through the ComponentMetaSchema door too; forwarded-key controls value-enforced; the strip contrast restated; interface/mirror census (eight tombstones, five live keys); serializer forward set read off disk; tree-scoped absence census |
Ablation 7 red / 16 green exactly as predicted. | correct |
| 6 | Docs: three guide fences stop authoring the keys; content/docs/releases/ untouched; item ③ (skills/**, governed) read-only and correctly left for its own PR |
Governed surface not ridden. | correct |
② semver
@object-ui/types minor ("Breaking for authored metadata", fixed-group convention) plus patch on the 24 packages whose registrations stop authoring inert keys. Correct.
③ Boundary flags
- PR chore(deps): resolve @objectstack/spec at 17.3.0 in the lockfile #7685 collision, declared by the seat on When bumping @objectstack/spec past objectstack#14075: list-view spec-parity pins need the CalendarConfig titleField-optional update #7122 (5556669730):
packages/plugin-detail/src/index.tsxsectionsentry — chore(deps): resolve @objectstack/spec at 17.3.0 in the lockfile #7685 edits itsdescription, this PR deletes itslabel. Union: chore(deps): resolve @objectstack/spec at 17.3.0 in the lockfile #7685's description text, nolabelkey (alabel:is atscerror and a named refusal after this lands). Merge queue arbitrates; whichever lands second mergesmainand keeps the union. WidgetInput's three now reader-less members are [finding]WidgetInput.label/defaultValue/advanced(packages/types/src/widget.ts) have no reader onceWidgetRegistrystops copying them onto the retiredComponentInputkeys — #7781's class, one face over #7911 — a ruling of its own, not this PR's.
Evidence and landing
Checks on b64d033b: 23 success / 3 skipped / 6 in progress (Type Check, four test shards, Build Docs); mergeable_state: behind (a main merge the queue performs, not a conflict); governed-surface predicate 0 of 130 paths. Clearing, same stroke: needs:contract-review off PR #7932 with provenance (the cards carry none). Landing (ready + auto-merge SQUASH) from this seat once every check is green — at its next check-in if the seat has not.
Generated by Claude Code
CI read at
|
… retires `packages/plugin-kanban/src/index.test.ts` was not in this PR's diff, so its `expect(onCardMoveInput?.advanced).toBe(true)` survived while `plugin-kanban/src/index.tsx` stopped authoring `advanced` — a live CI red (`Test (shard 4/4)`: `AssertionError: expected undefined to be true` at `index.test.ts:62:41`). `tsc` cannot catch it: `expect(x).toBe(true)` accepts a `never | undefined` receiver, so only running the suite finds it. The three sibling assertions beside it stay — `toBeDefined()`, `type === 'code'` and `description` all read live keys. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BAZFhALsQsGqxui8sNqM8s
…ssue-7493-component-input-retire-dead-keys
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
|
Seat note — the Gates section's anchor is stale; here is the current one. Posted as a comment rather than a body edit so the reserving seat's review target does not move under it. The body reads "final head Why there was a patch round. The patch is one deletion, no insertions, one file — the assertion line only. Its three siblings on the same receiver ( The bound was re-measured, not assumed. A receiver-shaped sweep over Re-runs on
The full farm was not re-run locally; that is CI's, currently in progress on this head. PR state untouched by the round: still draft, One field to disregard: the API still reports Generated by Claude Code |
|
Still red on The new failure is a collision with That pin file did not exist on the base this branch merged. PR #7922 landed at 04:02:18Z as So the pin asserts a fact this PR is the reason is no longer true. That makes it this PR's fix, in this PR: the three expected strings drop the Patch round 2 is dispatched with that scope plus three things the single visible failure does not bound: a controlled sweep for any other test that hard-codes an The PR stays DRAFT, unqueued, and reserved as it was. Next comment will carry the green head or a Generated by Claude Code |
…ssue-7493-component-input-retire-dead-keys
…tion lines (objectui#7779 pin) `packages/types/src/__tests__/object-view-unmirrored-keys-7779.test.ts` landed on `main` (PR #7922) one minute after this branch merged its base, so its `REGISTRATION_TEXT` hard-codes three `plugin-view/src/index.tsx` registration lines that still carry the `ComponentInput.label` key this PR retires. The pin asserted a fact this change is the reason is no longer true. Each expected string is copied off the registration source rather than composed by hand: only the `label: '…', ` fragment is dropped, every other character is the line as `packages/plugin-view/src/index.tsx` now reads. The assertion stays an exact `toContain` over three entries — the pin's intent (the three local literals are still registered as editable inputs) survives the retirement. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BAZFhALsQsGqxui8sNqM8s
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
|
GREEN on What round 2 changed: one file, 3 insertions / 3 deletions, plus a merge of The bound, not a guess. A sweep of the merged tree for the same collision shape — a registration entry pinned inside a quoted string — returns 17 hits on the primary pass and 23 on a superset pass over the 138 files that name a registration or renderer path as a string, plus a pass confirming no gate script pins registration text. Exactly one live site, the one fixed. Every other hit is a different key that happens to share a spelling: The corrected pin was shown to still fail. Re-inserting One correction to my earlier comment on this PR. I said this PR moves PR is DRAFT, unqueued, no auto-merge, Generated by Claude Code |
|
Landed by this seat at 05:07Z, on the reviewing seat's own instruction — not an override. The contract review (5556699068) closed with: "Landing (ready + auto-merge SQUASH) from this seat once every check is green — at its next check-in if the seat has not." That makes the dispatching seat the first mover and the Director seat the fallback, so with green in hand the stroke was mine to make. Preconditions re-read live immediately before, not carried from the green comment:
Sequence: Queued third, behind #7960 and #7961 and ahead of #7958. Two things follow this PR and are recorded so they are not lost when this shift ends:
The #7685 collision this PR's body predicted on Generated by Claude Code |
Refs #7493 (item ①)
Fixes #7781
Item ① of objectui#7493 under the maintainer's ruling A: retire (record 5556358261, 2026-09-06T02:32Z; verbatim 「第二批(4 项,契约形状族) 帮我处理,全部同意」), with objectui#7781's two keys folded into the same stroke. Items ② (
validateSchema(schema: any),domain:ui) and ③ (the governed skills guide line plus itsKNOWN_BARE_ANY_EXAMPLESrow) are not part of this PR; #7493 remains open for them. Dev subagent of thedomain:spec@ objectui PM seat, PM sessionsession_01BAZFhALsQsGqxui8sNqM8s; identity is the branch. Contract review:needs:contract-review(a published@object-ui/typesaccept set narrows on both faces). Placeholders below are spelled as words, never as bracket-shaped tokens, because the body sanitizer eats those.Premise, re-verified on
origin/main6a9ee323(the cut; the seat'sfa7d66c4had advanced by PR #7889)packages/types/src/base.ts:528export interface ComponentInput {withlabelat:603,defaultValueat:608,advancedat:628(the like-named members at:51,:140,:732belong to other interfaces and are untouched).packages/types/src/zod/base.zod.ts:301export const ComponentInputSchema = z.object({withlabelat:320,defaultValueat:321,advancedat:331(:326is the nested enum-option object's ownlabel, untouched).zod-mirror-parity.test.ts:577/:739: NOT touched by this PR — the tombstone route keeps every pair, so no ledger figure moves (the sibling Decision:ObjectViewSchema's ten unmirrored declared keys are LOCAL (objectui#7279 re-derivation) — mirror them, retire them, or defer to #2231? #7779's regions in that file are untouched too).packages/core/src/validation/schema-validator.ts:458and item ③skills/objectui/guides/plugin-development.md:103/scripts/check-skill-examples.mjs:558: read-only, not touched.The route was MEASURED before it was chosen — tombstone
On the BUILT face (
packages/types/dist/zod/index.zod.jsat the base;pnpm --filter @object-ui/types buildexit 0):ComponentInputSchema.safeParse({ name: 'content', type: 'string', notAKeyAtAll: 'anything' })returnssuccess: truewith the key ABSENT fromdata— an undeclared key is silently STRIPPED, not refused; the schema's def carries nocatchalland no strict flag. Control on the same call: the objectui#5905 tombstonemin: 1returnssuccess: false,code: 'invalid_type',path: ['min'], message beginningRETIRED (objectui#5905). Deletion would therefore have swallowed 1,162 authored values in silence, and the route is forced:?: neveron the interface plusretirementTombstone()on the mirror — the PR #7761 / #7769 / #7832 shape, and exactly what objectui#5905 did for its five keys (PR #7639's commit body: "Deleting the member outright stays the option NOT taken: ComponentInputSchema is a non-strict z.object, so an undeclared key is silently stripped"). Followed. The deletion-with-absence-pin route of PR #7743 / #7832 does not apply here.The census, re-derived with controls — the stop condition did not fire
Readers. Every non-test access of
.inputsunderpackages/**andapps/**enumerated on the tree:sdui-parser/src/index.ts:153(the serializer; forwardsname,type,required,enum,binding,description),codegen.ts:76/:151/:152andvalidate.ts:55/:58(the manifest shape — the boundary typeRegistryConfigLike.inputsatindex.ts:70-84has no slot for the three),core/src/registry/Registry.ts:392-394(input?.nameonly),components/src/renderers/layout/page.tsx:464(forwardsmeta?.inputsinto the serializer),core/src/registry/WidgetRegistry.ts:175(a WRITE). Receiver-shaped reads of.label/.defaultValue/.advancedon an input outside tests: exactly the threeWidgetRegistrycopy lines (:178,:179,:183) — writes, not reads. Zero production readers; the ruling's premise holds.Authorship. Depth-1 bracket-balanced scan over every
inputs: [array in tracked.ts/.tsx/.js/.jsx/.mjs/.cjsfiles (the instrument of report 5553590885): 121 files, 203 arrays, 952 input objects —label908,defaultValue245,advanced9; controls in the same pass over the same regionsname951,type951 (description193,enum119,required86,binding4). Identical to the report's reading. A WIDER instrument that also walks the three standaloneComponentInput[] = [arrays (containers.tsxPAGE_CONTAINER_INPUTS,plugin-detailCHATTER_INPUTS,plugin-gridGRID_QUERY_INPUTS): 985 objects —label941,defaultValue247,advanced9; controlsname984,type984. Neither instrument sees a bare named array (plugin-tree'streeInputs) or a typed record (html-elements.tsx'sPER_TAG_INPUTS);tscfound those two, which is what the tombstone is for. After the deletions the wide instrument readslabel0 /defaultValue0 /advanced0 withname984 /type984 unchanged, and the new pin carries that census as a tree-scoped test.What moves
base.ts:label?: never,defaultValue?: never,advanced?: neverwith the RETIRED docblocks (what each was, the census — zero readers, the serializer's six forwarded keys, the authorship counts — and what an author writes instead: nothing; the input'sname, the renderer's own fallback read, anddescriptionfor telling an author about a default).base.zod.ts: threeretirementTombstone()members, one guidance string each feeding both the parse-time message and.describe().PER_TAG_INPUTS(14label),treeInputs(2label),ELEMENT_DATA_SOURCE_INPUT'slabel(packages/core/src/data-scope/element-data-source.ts, its type and its object), and theWidgetRegistryseam copy (three lines;WidgetInputkeeps its own members). Noas any, no cast, no rename anywhere: the values are deleted because nothing reads them. Three comments that described a deleteddefaultValuewere rewritten (text.tsx,text-input.tsx,plugin-detail/index.tsx).defaultValue— re-pinned against the renderer's ACTUAL default; table below.packages/types/src/__tests__/component-input-retired-keys-7493.test.ts(23 tests): both faces refuse each key at path with the guidance (invalid_type, message equals.describe(), the remedy named per key), through theComponentMetaSchemadoor atinputs.0.labeltoo;@ts-expect-errorlegs at a real registration shape (and the registration's ownComponentMeta.labelshown live); controls — the five declared forwarded keys accepted with their values kept AND value-enforced (wrong-typedname/type/required/enum/descriptionrefused at their own path;bindingis objectui#6950's, undeclared on this face); the undeclared-key strip contrast (the route measurement, restated); an interface census read offbase.ts(exactly eight?: nevertombstones, exactly the five live keys) and the mirror agreeing member for member; the serializer's forward set read offsdui-parser/src/index.ts(exactly six); a tree-scoped absence census over everyinputs: [andComponentInput[] = [array underpackages/STAR/srcandapps/STAR/srcwithname/typefloors as controls (skips only this pin and its sibling pin, reason stated in the file).component-input-retired-constraint-keys.test.ts:LIVE_INPUTstops authoringlabel(it is a tombstone now); nothing else moves.content/docs/guide/architecture.md,component-registry.md,plugin-development.mdfences stop authoring the keys (a default moves intodescription); the plugin-development prose no longer says the designer readsComponentInputentries (it never did) and names the six forwarded keys.content/docs/releases/untouched.packages/types/src/widget.tsdocblock: a third divergence recorded —WidgetInput.label/defaultValue/advancedstay declared and writable on the widget-manifest face, and are now measured reader-less (filed as [finding]WidgetInput.label/defaultValue/advanced(packages/types/src/widget.ts) have no reader onceWidgetRegistrystops copying them onto the retiredComponentInputkeys — #7781's class, one face over #7911, no ruling implied)..changeset/7493-componentinput-retire-label-defaultvalue-advanced.md:@object-ui/types: minor, opening "Breaking for authored metadata:", the FROM → TO per key, the route measurement, the accept-set change in words, the migration (delete the key);patchentries for the 24 packages whose registrations stopped authoring the keys.The nine
defaultValue-reading test filesapps/console/src/__tests__/public-block-binding-reach.test.tsxapps/console/src/__tests__/record-block-record-reach.test.tsxSAMPLE_BY_INPUTtable beside the read each mirrors (relationshipValueField || 'id',showHeader ?? false,location || 'record_header',align || 'end',variant || 'default',size || 'sm') — measured: with the generic type samples three blocks stopped reaching (3 red), with the restated defaults 29 / 29 greenpackages/components/src/__tests__/icon-renderer-declared-default.test.tsscripts/__tests__/check-lucide-icon-record-names.test.ts:1036requires it as the objectui#5936 record, and now pins the one remaining declared spelling (meta.iconis a non-empty string) plus the input's absent default. No renderer default exists to re-pin against: an absenticonname renders the placeholder branch by design (objectui#5631)packages/components/src/__tests__/record-picker-inputs-spec-parity.test.tsfilter— kept and the case renamedpackages/components/src/__tests__/text-input-inputs-spec-parity.test.tsdefaultValueentry's own defaultpackages/layout/src/__tests__/appSchemaRendererMobileNavMode.test.tsxAppSchemaRenderer.tsx's destructuring default (mobileNavMode = 'drawer', read off disk) and the description's"drawer" (default)packages/plugin-detail/src/__tests__/recordDetailsInputs.spec-parity.test.tsrecord-details.tsx's own readsschema.inlineEdit ?? trueandschema.showHeader ?? false(read off disk); the description regexes keptpackages/plugin-detail/src/__tests__/recordRelatedListInputs.spec-parity.test.tsrecord-related-list.tsx'srelationshipValueField || 'id'(read off disk) and the description'sDefaults to "id"; the spec-parse fallback assertion keptpackages/plugin-editor/src/index.test.tsdefaultValueassertion deleted;defaultProps.readOnly === false— the renderer's actual default — was already pinned four lines aboveGates — final head
b64d033bc, exit codes captured before any pipe, heavy runs under the shared verify lockpnpm --filter @object-ui/types build: exit 0 (dist completeness: 1 package(s) complete (124 emitted files verified)).pnpm --filter @object-ui/types type-check(tsc --noEmit && tsc -p tsconfig.examples.json && tsc -p tsconfig.test.json, script name echoed): exit 0.pnpm exec vitest run --maxWorkers=2overcomponent-input-retired-keys-7493,component-input-retired-constraint-keys,zod-mirror-parity:Test Files 3 passed (3) · Tests 55 passed (55)— the parity verdict is green with no ledger movement.turbo run build --concurrency=2, each package's build is itstsc/ typed vite build): components' dependency closure 7 / 7; components + layout + fields + sdui-parser 11 / 11; ten plugins 23 / 23; the remaining plugins + app-shell 30 / 30; cli + map + markdown + timeline 17 / 17; after the merge app-shell + timeline 30 / 30 — every callVERDICT command-exit 0. The two RED intermediate readings were real finds (html-elements.tsxPER_TAG_INPUTS,plugin-treetreeInputs), fixed and rebuilt.type-check(tsc --noEmit && tsc -p tsconfig.test.json, tests included) on core, components, layout, plugin-tree, plugin-editor, plugin-detail, the sixteen other plugins, app-shell and console (tsc --noEmit && tsc -b tsconfig.node.json): every one exit 0 with its script name echoed (one RED reading — a duplicate import the re-pin introduced — fixed in its own commit and re-read green).pnpm exec vitest run --maxWorkers=2 packages/core/ packages/layout/ packages/plugin-detail/ packages/plugin-editor/ packages/plugin-tree/+ the two console reach files: first runTest Files 1 failed | 281 passed (282) · Tests 3 failed | 3987 passed (3990)(the record-reach probe, see the table); the two reach files re-runTest Files 2 passed (2) · Tests 29 passed (29).pnpm exec vitest run --maxWorkers=2 packages/components/:Test Files 233 passed (233) · Tests 2149 passed (2149).pnpm exec eslintover the 125 changed code files (the rooteslint.config.jsis the repository's only eslint config, so an untouched file's verdict cannot move): exit 0,0 errors, 715 warnings(pre-existingno-explicit-anywarnings). The per-packagepnpm lintfarm is CI's.node scripts/check-changeset-presence.mjs: exit 0 (126 source file(s) of 25 released package(s) changed, and this change declares 1 changeset(s));check-changeset-fixed/-overwrite/-no-major: exit 0 each.node scripts/check-control-bytes.mjs: exit 0 (scanned 6402 tracked text file(s)); self-scangrep -naPover every changed file: no hit.pnpm check:spec-symbolsexit 0 ·pnpm check:doc-fencesexit 0 ·pnpm check:doc-typesexit 0 (Every documented component type is registered).node scripts/check-doc-snippet-types.mjson the fully built tree: exit 0 (456 of 456 block(s) judged, 0 failed).node scripts/check-skill-examples.mjs(item ③'s surface, read only): exit 0 —13 of 13 ts fence(s) judged, 0 failed;Bare any: 1 finding(s) … 1 declared in KNOWN_BARE_ANY_EXAMPLES … 0 declared row(s) no longer red— the baseline row is NOT stale, because the guide still carriesdefaultValue?: any.scripts/pm/check-governed-merges.mjs --test, the final 130-path list):0 of 130 path(s) hit the register … NOT governed.pnpm testover the other downstream packages and the per-packagepnpm lintfarm.Ablation (Clause-② yes) — predicted in writing before the run
One script under the verify lock,
trap restore EXIT INT TERM, absolute paths fromgit rev-parse --show-toplevel, the implementation committed first. Mutation: the zod face alone back to the pinned base (git checkout 6a9ee323 -- packages/types/src/zod/base.zod.ts); on-disk proof: markerRETIRED (objectui#7493)count 3 → 0, old spellingdefaultValue: z.any().optional()count 1,git hash-objectequals the base blobec957d27…; types dist rebuilt under mutation (exit 0), marker count indist/zod/base.zod.js0. Prediction: the zod-face cases go RED — the three per-key refusals, the nested registration door, the literaldefaultValuestring, "the three stay in the mirror's shape", the mirror-agrees census (seven) — while thetsclegs, the forwarded-key controls (accepted and the five value-enforced), the undeclared-key strip contrast, the interface census, the serializer read and the tree census stay GREEN (sixteen). Observed:Tests 7 failed | 16 passed (23), exactly those seven. Restore:git checkout HEAD -- ABSOLUTE_PATH;git hash-objectequals the HEAD blob651b1037…(IDENTICAL),git diff HEAD -- pathEMPTY,git statusclean for the file; dist rebuilt (exit 0), marker back to 3; the pinTests 23 passed (23).Overlaps and readings the seat needs
ObjectViewSchema's ten unmirrored declared keys are LOCAL (objectui#7279 re-derivation) — mirror them, retire them, or defer to #2231? #7779's sibling:packages/types/src/__tests__/zod-mirror-parity.test.tsis not in this diff at all.packages/plugin-detail/src/index.tsxon thesectionsinput's line (itsdescriptiontext); this PR deleteslabel: 'Sections'on that same line, so a textual conflict is likely when the second of the two lands. The union is chore(deps): resolve @objectstack/spec at 17.3.0 in the lockfile #7685's description text with nolabel. Merge queue, no hand-ordering.origin/mainwas merged before opening (merge commitc333acc4, four commits, clean;content/docs/guide/architecture.mdwas touched by docs(guide): repair the seven ${…} sites on keys with no carriage row (objectui#7872) #7900 at a different region).skills/objectui/guides/plugin-development.mdrestatesComponentInputat:95-107withlabel?: string; defaultValue?: any; advanced?: boolean— three RETIRED keys now — and its:46-62registration fence authorslabel:on three inputs (unmarked, so the gate does not compile it). Under ruling A the guide's honest edit is to drop those three lines and the fence'slabel:writes, and theKNOWN_BARE_ANY_EXAMPLESrow (:558, still anchored to:92while the line sits at:103) retires with theanyit declares.label/defaultValue/advanced; that they now have no reader either is [finding]WidgetInput.label/defaultValue/advanced(packages/types/src/widget.ts) have no reader onceWidgetRegistrystops copying them onto the retiredComponentInputkeys — #7781's class, one face over #7911, filed for a ruling of its own.Per-file deletions (110 files, 1,199 keys; the instrument's own count,
PER_TAG_INPUTS/ELEMENT_DATA_SOURCE_INPUT/ theWidgetRegistrycopy not included)packages/plugin-detail/src/index.tsxpackages/plugin-chatbot/src/renderer.tsxpackages/plugin-form/src/index.tsxpackages/plugin-dashboard/src/index.tsxpackages/plugin-designer/src/index.tsxpackages/plugin-view/src/index.tsxpackages/components/src/renderers/layout/containers.tsxpackages/plugin-grid/src/index.tsxpackages/plugin-ai/src/index.tsxpackages/components/src/renderers/basic/elements.tsxpackages/components/src/renderers/complex/data-table.tsxpackages/plugin-charts/src/index.tsxpackages/components/src/renderers/form/input.tsxpackages/components/src/renderers/form/form.tsxpackages/plugin-kanban/src/index.tsxpackages/plugin-calendar/src/calendar-view-renderer.tsxpackages/components/src/renderers/navigation/sidebar.tsxpackages/plugin-list/src/index.tsxpackages/components/src/renderers/action/action-button.tsxpackages/components/src/renderers/action/action-bar.tsxpackages/plugin-timeline/src/renderer.tsxpackages/components/src/renderers/basic/data-list.tsxpackages/components/src/renderers/action/action-group.tsxpackages/components/src/renderers/overlay/sheet.tsxpackages/components/src/renderers/layout/flex.tsxpackages/plugin-editor/src/index.tsxpackages/components/src/renderers/overlay/alert-dialog.tsxpackages/components/src/renderers/action/action-icon.tsxpackages/components/src/renderers/overlay/drawer.tsxpackages/components/src/renderers/overlay/dialog.tsxpackages/components/src/renderers/layout/stack.tsxpackages/components/src/renderers/layout/grid.tsxpackages/components/src/renderers/form/slider.tsxpackages/components/src/renderers/basic/record-picker.tsxpackages/components/src/renderers/overlay/tooltip.tsxpackages/components/src/renderers/layout/page.tsxpackages/components/src/renderers/form/button.tsxpackages/components/src/renderers/basic/text-input.tsxpackages/plugin-report/src/index.tsxpackages/components/src/renderers/overlay/popover.tsxpackages/components/src/renderers/overlay/hover-card.tsxpackages/components/src/renderers/layout/container.tsxpackages/components/src/renderers/form/toggle.tsxpackages/components/src/renderers/feedback/toast.tsxpackages/components/src/renderers/disclosure/toggle-group.tsxpackages/components/src/renderers/complex/resizable.tsxpackages/components/src/renderers/complex/carousel.tsxpackages/components/src/renderers/action/action-menu.tsxpackages/layout/src/index.tspackages/components/src/renderers/overlay/dropdown-menu.tsxpackages/components/src/renderers/form/textarea.tsxpackages/components/src/renderers/form/select.tsxpackages/components/src/renderers/form/radio-group.tsxpackages/components/src/renderers/feedback/sonner.tsxpackages/components/src/renderers/feedback/loading.tsxpackages/plugin-charts/src/ObjectChart.tsxpackages/components/src/renderers/layout/aspect-ratio.tsxpackages/components/src/renderers/form/file-upload.tsxpackages/components/src/renderers/form/combobox.tsxpackages/components/src/renderers/form/checkbox.tsxpackages/components/src/renderers/disclosure/collapsible.tsxpackages/components/src/renderers/disclosure/accordion.tsxpackages/components/src/renderers/data-display/list.tsxpackages/components/src/renderers/data-display/avatar.tsxpackages/components/src/renderers/data-display/alert.tsxpackages/components/src/renderers/complex/table.tsxpackages/components/src/renderers/complex/scroll-area.tsxpackages/components/src/renderers/basic/pagination.tsxpackages/components/src/renderers/basic/icon.tsxpackages/components/src/renderers/basic/button-group.tsxpackages/plugin-timeline/src/index.tsxpackages/plugin-map/src/index.tsxpackages/plugin-gantt/src/index.tsxpackages/plugin-calendar/src/index.tsxpackages/components/src/renderers/overlay/context-menu.tsxpackages/components/src/renderers/navigation/header-bar.tsxpackages/components/src/renderers/form/date-picker.tsxpackages/components/src/renderers/feedback/empty.tsxpackages/components/src/renderers/data-display/statistic.tsxpackages/components/src/renderers/data-display/badge.tsxpackages/components/src/renderers/complex/filter-builder.tsxpackages/components/src/renderers/basic/text.tsxpackages/components/src/renderers/layout/tabs.tsxpackages/components/src/renderers/layout/card.tsxpackages/components/src/renderers/form/switch.tsxpackages/components/src/renderers/form/input-otp.tsxpackages/components/src/renderers/form/command.tsxpackages/components/src/renderers/form/calendar.tsxpackages/components/src/renderers/feedback/toaster.tsxpackages/components/src/renderers/feedback/spinner.tsxpackages/components/src/renderers/feedback/skeleton.tsxpackages/components/src/renderers/feedback/progress.tsxpackages/components/src/renderers/data-display/tree-view.tsxpackages/components/src/renderers/data-display/breadcrumb.tsxpackages/components/src/renderers/basic/separator.tsxpackages/components/src/renderers/basic/image.tsxpackages/plugin-tree/src/index.tsxpackages/plugin-markdown/src/index.tsxpackages/components/src/renderers/form/label.tsxpackages/components/src/renderers/data-display/kbd.tsxpackages/components/src/renderers/overlay/menubar.tsxpackages/components/src/renderers/layout/semantic.tsxpackages/components/src/renderers/layout/box.tsxpackages/components/src/renderers/basic/span.tsxpackages/components/src/renderers/basic/navigation-menu.tsxpackages/components/src/renderers/basic/html.tsxpackages/components/src/renderers/basic/html-elements.tsxpackages/components/src/renderers/basic/div.tsxpackages/app-shell/src/views/record-attachments-renderer.tsxpackages/app-shell/src/views/record-approvals-renderer.tsx🤖 Generated with Claude Code
https://claude.ai/code/session_01BAZFhALsQsGqxui8sNqM8s
Generated by Claude Code